package RobotBounded

// 指令
const (
	GO    = 'G'
	LEFT  = 'L'
	RIGHT = 'R'
)

// 方向
var directions = [...][2]int32{{0, 1}, {1, 0}, {0, -1}, {-1, 0}}

// Robot 机器人
type Robot struct {
	direction int32
	x         int32
	y         int32
}

func (r *Robot) goStraight() {
	r.x, r.y = r.x+directions[r.direction][0], r.y+directions[r.direction][1]
}

func (r *Robot) left() {
	if r.direction <= 0 {
		r.direction = 3
	} else {
		r.direction = (r.direction - 1) % 4
	}
}
func (r *Robot) right() {
	r.direction = (r.direction + 1) % 4
}

// 是否在原点
func (r *Robot) isInOrigin() bool {
	return r.x == 0 && r.y == 0
}

// 是否在向前走
func (r *Robot) isGoing() bool {
	return r.direction == 0
}

// https://leetcode-cn.com/problems/robot-bounded-in-circle/
func isRobotBounded(instructions string) bool {
	robot := new(Robot)
	for _, s := range instructions {
		switch s {
		case GO:
			robot.goStraight()
		case LEFT:
			robot.left()
		case RIGHT:
			robot.right()
		}
	}
	return robot.isInOrigin() || !robot.isGoing()
}

func isRobotBounded2(instructions string) bool {
	x, y := 0, 0
	dirs := [...][2]int{{0, 1}, {1, 0}, {0, -1}, {-1, 0}}
	var i int
	for _, c := range instructions {
		switch c {
		case GO:
			x, y = x+dirs[i%4][0], y+dirs[i%4][1]
		case LEFT:
			if i <= 0 {
				i = 3
			} else {
				i -= 1
			}
		case RIGHT:
			i += 1
		}
	}
	return (x == 0 && y == 0) || (i%4 != 0)
}
